﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using OpenCvSharp.Util;
using System.Diagnostics;

namespace MainFrame
{
    public class visionProc
    {
        public static void Fweld(List<byte[]> imagelist)
        {
            if (imagelist.Count>0&&GlobalImage.hik_Fweld!=null)
            {
                byte[] imagebyte = imagelist[imagelist.Count - 1];
                GlobalImage.FweldMat = new Mat(GlobalImage.hik_Fweld.m_ImgHeight, 
                    GlobalImage.hik_Fweld.m_ImgWidth, MatType.CV_8UC1, imagebyte);
                switch (GlobalImage.imageProcMode_F)
                {
                    case (int)e_imageProcMode.calibrate:
                        GlobalImage.Fcalib_task = Fcalibrate(GlobalImage.FweldMat);
                        //displalyImage.displayImage_F(GlobalImage.FweldMat);
                        break;
                    case (int)e_imageProcMode.identify:
                        //GlobalImage.F_identify_task =F_identify(GlobalImage.FweldMat);
                        break;
                    case (int)e_imageProcMode.justDisplay:
                        displalyImage.displayImage_F(GlobalImage.FweldMat);
                        break;
                    default:
                        displalyImage.displayImage_F(GlobalImage.FweldMat);
                        break;
                }              
            }           
        }
        public static void Lweld(List<byte[]> imagelist)
        {
            if (imagelist.Count > 0 && GlobalImage.hik_Lweld != null)
            {
                byte[] imagebyte = imagelist[imagelist.Count - 1];
                GlobalImage.LweldMat = new Mat(GlobalImage.hik_Lweld.m_ImgHeight,
                    GlobalImage.hik_Lweld.m_ImgWidth, MatType.CV_8UC1, imagebyte);
                switch (GlobalImage.imageProcMode_L)
                {
                    case (int)e_imageProcMode.calibrate:
                        GlobalImage.Lcalib_task = Lcalibrate(GlobalImage.LweldMat);
                        break;
                    case (int)e_imageProcMode.identify:
                        //GlobalImage.L_identify_task = L_identify(GlobalImage.LweldMat);
                        //displalyInfo.displayInfoMain(GlobalImage.L_identify_task.ToString());
                        break;
                    case (int)e_imageProcMode.justDisplay:
                        displalyImage.displayImage_L(GlobalImage.LweldMat);
                        break;
                    default:
                        displalyImage.displayImage_L(GlobalImage.LweldMat);
                        break;
                }
            }
        }
        public static void measure(List<byte[]> imagelist)
        {
            if (imagelist.Count > 0 && GlobalImage.hik_Meausre != null)
            {
                byte[] imagebyte = imagelist[imagelist.Count - 1];
                GlobalImage.MeasureMat = null;
                GlobalImage.MeasureMat = new Mat(GlobalImage.hik_Meausre.m_ImgHeight,
                    GlobalImage.hik_Meausre.m_ImgWidth, MatType.CV_8UC1, imagebyte);
                switch (GlobalImage.imageProcMode_M)
                {
                    case (int)e_imageProcMode.calibrate:
                        GlobalImage.Mcalib_task = Mcalibrate(GlobalImage.MeasureMat);
                        break;
                    case (int)e_imageProcMode.identify:
                        //GlobalImage.M_identify_task = M_identify(GlobalImage.MeasureMat);
                        break;
                    case (int)e_imageProcMode.justDisplay:
                        displalyImage.displayImage_M(GlobalImage.MeasureMat);
                        break;
                    default:
                        displalyImage.displayImage_M(GlobalImage.MeasureMat);
                        break;
                }
            }
        }

        public static Task<double[]> Fcalibrate(Mat input)
        {
            Task<double[]> temp;
            List<double[]> findcenter=new List<double[]>();
            temp=Task.Run(() =>
            {
                double[] xy = new double[2];
                try
                {
                    opencvProc.FindCircle(input, true, 300, 100000, 10, ref findcenter);
                    xy[0] = findcenter[0][0];
                    xy[1] = findcenter[0][1];
                    opencvProc.MarkerCross(input,xy[0],xy[1],50);
                    displalyImage.displayImage_F(input);
                    return xy;
                }
                catch (System.Exception ex)
                {
                    displalyInfo.displayInfoMain("标定算法出错：" + ex.Message);
                    return xy;
                }
            });
            //displalyImage.displayImage_F(input);
            return temp;
        }
        public static Task<double[]> Lcalibrate(Mat input)
        {
            Task< double[] > temp;
            List<double[]> findcenter = new List<double[]>();
            temp = Task.Run(() =>
            {
                double[] xy = new double[2];
                try
                {
                    opencvProc.FindCircle(input, true, 300, 100000, 10, ref findcenter);
                    xy[0] = findcenter[0][0];
                    xy[1] = findcenter[0][1];
                    opencvProc.MarkerCross(input, xy[0], xy[1], 50);
                    displalyImage.displayImage_L(input);
                    return xy;
                }
                catch (System.Exception ex)
                {
                    displalyInfo.displayInfoMain("标定算法出错：" + ex.Message);
                    return xy;
                }
            });
            
            return temp;
        }
        public static Task<double[]> Mcalibrate(Mat input)
        {
            Task<double[]> temp;
            List<double[]> findcenter = new List<double[]>();
            temp = Task.Run(() =>
            {
                double[] xy = new double[2];
                try
                {
                    opencvProc.FindCircle(input, true, 300, 100000, 10, ref findcenter);
                    xy[0] = findcenter[0][0];
                    xy[1] = findcenter[0][1];
                    opencvProc.MarkerCross(input, xy[0], xy[1], 50);
                    displalyImage.displayImage_M(input);
                    return xy;
                }
                catch (System.Exception ex)
                {
                    displalyInfo.displayInfoMain("标定算法出错：" + ex.Message);
                    return xy;
                }
                
            });
            
            return temp;
        }
        //    public static Task<double[]> F_identify(Mat input)
        //    {
        //        if (input == null || GlobalVar.typedata_g == null)
        //        {
        //            displalyInfo.displayInfoMain("F_indetify 输入或型号数据不能为空");
        //            return null;
        //        }
        //        double[] result = new double[3];
        //        double[] xy = new double[3];
        //        Task<double[]> temp;
        //        Mat tempMat = input.Clone();
        //        opencvProc.ThresholdImage(tempMat, GlobalVar.typedata_g.FWsnap_thresholdL, GlobalVar.typedata_g.FWsnap_thresholdH,
        //            GlobalVar.typedata_g.FWsnap_median, GlobalVar.typedata_g.FWsnap_gauss);
        //        //double[] findcenter = new double[2] { 2.212, 3.66 };
        //        temp = Task.Run(() =>
        //        {

        //            try
        //            {
        //                //opencvProc.FindCircle(input, true, 10, 800000, 10, ref findcenter);
        //                opencvProc.MatchTemplate(tempMat, GlobalVar.typedata_g.templateF, 2, GlobalVar.typedata_g.FmatchScore, ref result);
        //                if (result == null)
        //                {
        //                    displalyInfo.displayInfoMain("F_indetify 没有找到匹配结果");
        //                    return null;
        //                }
        //                xy[0] = result[0];
        //                xy[1] = result[1];
        //                xy[2] = result[2];
        //                return xy;
        //            }
        //            catch (System.Exception ex)
        //            {
        //                displalyInfo.displayInfoMain("识别出错：" + ex.Message);
        //                return null;
        //            }
        //        });

        //        return temp;
        //    }
        //    public static Task<double[]> L_identify(Mat input)
        //    {
        //        if (input==null||GlobalVar.typedata_g==null)
        //        {
        //            displalyInfo.displayInfoMain("L_indetify 输入或型号数据不能为空");
        //            return null;
        //        }
        //        double[] result = new double[3];
        //        double[] xy = new double[3];
        //        Task<double[]> temp;
        //        Mat tempMat = input.Clone();
        //        opencvProc.ThresholdImage(tempMat, GlobalVar.typedata_g.LWsnap_thresholdL, GlobalVar.typedata_g.LWsnap_thresholdH, 
        //            GlobalVar.typedata_g.LWsnap_median, GlobalVar.typedata_g.LWsnap_gauss);
        //        //double[] findcenter = new double[2] { 2.212, 3.66 };
        //        temp = Task.Run(() =>
        //        {

        //            try
        //            {
        //                //opencvProc.FindCircle(input, true, 10, 800000, 10, ref findcenter);
        //                opencvProc.MatchTemplate(tempMat, GlobalVar.typedata_g.templateL, 2, GlobalVar.typedata_g.LmatchScore, ref result);
        //                if (result==null)
        //                {
        //                    displalyInfo.displayInfoMain("L_indetify 没有找到匹配结果");
        //                    return null;
        //                }
        //                xy[0] = result[0];
        //                xy[1] = result[1];
        //                xy[2] = result[2];
        //                return xy;
        //            }
        //            catch (System.Exception ex)
        //            {
        //                displalyInfo.displayInfoMain("识别出错：" + ex.Message);
        //                return null;
        //            }
        //        });

        //        return temp;
        //    }

        //    public static Task<double[]> M_identify(Mat input)
        //    {
        //        if (input == null || GlobalVar.typedata_g == null)
        //        {
        //            displalyInfo.displayInfoMain("M_indetify 输入或型号数据不能为空");
        //            return null;
        //        }
        //        double[] result = new double[5];
        //        double[] xy = new double[5];
        //        Task<double[]> temp;
        //        Mat tempMat = input.Clone();

        //        opencvProc.ThresholdImage(tempMat, GlobalVar.typedata_g.Msnap_thresholdL, GlobalVar.typedata_g.Msnap_thresholdH,
        //            GlobalVar.typedata_g.Msnap_median, GlobalVar.typedata_g.Msnap_gauss);
        //        //double[] findcenter = new double[2] { 2.212, 3.66 };
        //        temp = Task.Run(() =>
        //        {

        //            try
        //            {
        //                #region indentify
        //                Stopwatch sw = new Stopwatch();
        //                sw.Restart();

        //                opencvProc.ThresholdImage(input, GlobalVar.typedata_g.Msnap_thresholdL, GlobalVar.typedata_g.Msnap_thresholdH,
        //                    GlobalVar.typedata_g.Msnap_median, GlobalVar.typedata_g.Msnap_gauss, MorphTypes.Close);
        //                Mat output = input.Clone();
        //                double[] cannyLimit = new double[] { GlobalVar.typedata_g.Msnap_cannyL, GlobalVar.typedata_g.Msnap_cannyH };
        //                double[] outline = new double[2];
        //                float[] center = new float[] { (float)GlobalVar.typedata_g.Msnap_centerX, (float)GlobalVar.typedata_g.Msnap_centerY };
        //                opencvProc.PositionAdjust(input, output, cannyLimit, center, GlobalVar.typedata_g.Msnap_IsDisplayContous, ref outline);
        //                GlobalImage.MeasureMat = input;
        //                OpenCvSharp.Rect recRoiUp = new OpenCvSharp.Rect(340, 120, 1500, 250);
        //                OpenCvSharp.Rect recRoiDown = new OpenCvSharp.Rect(340, 2350, 1500, 250);
        //                OpenCvSharp.Rect recRoiLeft = new OpenCvSharp.Rect(30, 500, 280, 1600);
        //                OpenCvSharp.Rect recRoiRight = new OpenCvSharp.Rect(2250, 500, 280, 600);
        //                OpenCvSharp.Rect recRoiSmall = new OpenCvSharp.Rect(3730, 1530, 90, 100);

        //                Mat roiMatUp = new Mat(output, recRoiUp);
        //                Mat roiMatDown = new Mat(output, recRoiDown);
        //                Mat roiMatLeft = new Mat(output, recRoiLeft);
        //                Mat roiMatRight = new Mat(output, recRoiRight);
        //                Mat roiMatSamll = new Mat(output, recRoiSmall);

        //                OpenCvSharp.Point[][] contoursUp;
        //                OpenCvSharp.Point[][] contoursDown;
        //                OpenCvSharp.Point[][] contoursLeft;
        //                OpenCvSharp.Point[][] contoursRight;
        //                OpenCvSharp.Point[][] contoursSmall;

        //                Point2f[] ptf = new Point2f[4];
        //                HierarchyIndex[] hier;
        //                HierarchyIndex[] hierDown;
        //                OpenCvSharp.Size wholesize;
        //                OpenCvSharp.Point offsetpointUp;
        //                roiMatUp.LocateROI(out wholesize, out offsetpointUp);
        //                OpenCvSharp.Point offsetpointDown;
        //                roiMatDown.LocateROI(out wholesize, out offsetpointDown);
        //                OpenCvSharp.Point offsetpointLeft;
        //                roiMatLeft.LocateROI(out wholesize, out offsetpointLeft);
        //                OpenCvSharp.Point offsetpointRight;
        //                roiMatRight.LocateROI(out wholesize, out offsetpointRight);
        //                OpenCvSharp.Point offsetpointSmall;
        //                roiMatSamll.LocateROI(out wholesize, out offsetpointSmall);

        //                Cv2.Canny(roiMatUp, roiMatUp, 140, 300);
        //                Cv2.Canny(roiMatDown, roiMatDown, 140, 300);
        //                Cv2.Canny(roiMatLeft, roiMatLeft, 140, 300);
        //                Cv2.Canny(roiMatRight, roiMatRight, 140, 300);
        //                Cv2.Canny(roiMatSamll, roiMatSamll, 140, 300);

        //                Line2D upline;
        //                Line2D downline;
        //                Line2D rightline;
        //                Line2D leftline;
        //                Line2D smallline;

        //                #region upline
        //                Cv2.FindContours(roiMatUp, out contoursUp, out hier, RetrievalModes.External, ContourApproximationModes.ApproxNone, offsetpointUp);
        //                if (contoursUp.Length > 1)
        //                {
        //                    Dictionary<int, double> meanXup = new Dictionary<int, double>();
        //                    int TotalXup = 0;
        //                    for (int i = 0; i < contoursUp.Length; i++)
        //                    {
        //                        TotalXup = 0;
        //                        if (contoursUp[i].Length < 50)
        //                        {
        //                            continue;
        //                        }
        //                        for (int j = 0; j < contoursUp[i].Length; j++)
        //                        {
        //                            TotalXup += contoursUp[i][j].Y;
        //                        }
        //                        meanXup.Add(i, TotalXup / contoursUp[i].Length);
        //                    }
        //                    var meanXup_descend = from meanXd_up in meanXup orderby meanXd_up.Value ascending select meanXd_up;
        //                    upline = Cv2.FitLine(contoursUp[meanXup_descend.First().Key], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                else
        //                {
        //                    upline = Cv2.FitLine(contoursUp[0], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                #endregion
        //                #region downLine
        //                Cv2.FindContours(roiMatDown, out contoursDown, out hierDown, RetrievalModes.External, ContourApproximationModes.ApproxNone, offsetpointDown);
        //                if (contoursDown.Length > 1)
        //                {
        //                    Dictionary<int, double> meanXdown = new Dictionary<int, double>();
        //                    int TotalXdown = 0;
        //                    for (int i = 0; i < contoursDown.Length; i++)
        //                    {
        //                        TotalXdown = 0;
        //                        if (contoursDown[i].Length < 50)
        //                        {
        //                            continue;
        //                        }
        //                        for (int j = 0; j < contoursDown[i].Length; j++)
        //                        {
        //                            TotalXdown += contoursDown[i][j].Y;
        //                        }
        //                        meanXdown.Add(i, TotalXdown / contoursDown[i].Length);
        //                    }
        //                    var meanXdown_descend = from meanXd_down in meanXdown orderby meanXd_down.Value descending select meanXd_down;
        //                    downline = Cv2.FitLine(contoursDown[meanXdown_descend.First().Key], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                else
        //                {
        //                    downline = Cv2.FitLine(contoursDown[0], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                #endregion
        //                #region leftLine
        //                Cv2.FindContours(roiMatLeft, out contoursLeft, out hier, RetrievalModes.External, ContourApproximationModes.ApproxNone, offsetpointLeft);
        //                if (contoursLeft.Length > 1)
        //                {
        //                    Dictionary<int, double> meanXleft = new Dictionary<int, double>();
        //                    int TotalXleft = 0;
        //                    for (int i = 0; i < contoursLeft.Length; i++)
        //                    {
        //                        TotalXleft = 0;
        //                        if (contoursLeft[i].Length < 50)
        //                        {
        //                            continue;
        //                        }
        //                        for (int j = 0; j < contoursLeft[i].Length; j++)
        //                        {
        //                            TotalXleft += contoursLeft[i][j].X;
        //                        }
        //                        meanXleft.Add(i, TotalXleft / contoursLeft[i].Length);
        //                    }
        //                    var meanXleft_descend = from meanXd_left in meanXleft orderby meanXd_left.Value ascending select meanXd_left;

        //                    leftline = Cv2.FitLine(contoursLeft[meanXleft_descend.First().Key], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                else
        //                {
        //                    leftline = Cv2.FitLine(contoursLeft[0], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                #endregion
        //                #region RightLine
        //                Cv2.FindContours(roiMatRight, out contoursRight, out hierDown, RetrievalModes.External, ContourApproximationModes.ApproxNone, offsetpointRight);
        //                if (contoursRight.Length > 1)
        //                {
        //                    Dictionary<int, double> meanXright = new Dictionary<int, double>();
        //                    int TotalXright = 0;
        //                    for (int i = 0; i < contoursRight.Length; i++)
        //                    {
        //                        TotalXright = 0;
        //                        if (contoursRight[i].Length < 50)
        //                        {
        //                            continue;
        //                        }
        //                        for (int j = 0; j < contoursRight[i].Length; j++)
        //                        {
        //                            TotalXright += contoursRight[i][j].X;
        //                        }
        //                        meanXright.Add(i, TotalXright / contoursRight[i].Length);
        //                    }
        //                    var meanXright_descend = from meanXd_right in meanXright orderby meanXd_right.Value descending select meanXd_right;
        //                    rightline = Cv2.FitLine(contoursRight[meanXright_descend.First().Key], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                else
        //                {
        //                    rightline = Cv2.FitLine(contoursRight[0], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                }
        //                #endregion
        //                #region smallLine
        //                //Cv2.FindContours(roiMatSamll, out contoursSmall, out hier, RetrievalModes.External, ContourApproximationModes.ApproxNone, offsetpointSmall);
        //                //if (contoursSmall.Length > 1)
        //                //{
        //                //    Dictionary<int, double> meanXsmall = new Dictionary<int, double>();
        //                //    int TotalXsmall = 0;
        //                //    for (int i = 0; i < contoursSmall.Length; i++)
        //                //    {
        //                //        TotalXsmall = 0;
        //                //        if (contoursSmall[i].Length < 50)
        //                //        {
        //                //            continue;
        //                //        }
        //                //        for (int j = 0; j < contoursSmall[i].Length; j++)
        //                //        {
        //                //            TotalXsmall += contoursSmall[i][j].X;
        //                //        }
        //                //        meanXsmall.Add(i, TotalXsmall / contoursSmall[i].Length);
        //                //    }
        //                //    var meanXsmall_descend = from meanXd_small in meanXsmall orderby meanXd_small.Value descending select meanXd_small;
        //                //    var l = meanXsmall_descend;
        //                //    smallline = Cv2.FitLine(contoursSmall[meanXsmall.First().Key], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                //}
        //                //else
        //                //{
        //                //    smallline = Cv2.FitLine(contoursSmall[0], DistanceTypes.Huber, 0, 0.01, 0.01);
        //                //}
        //                #endregion
        //                double circleUp = upline.Distance(GlobalVar.typedata_g.Msnap_centerX, GlobalVar.typedata_g.Msnap_centerY);
        //                double circleDown = downline.Distance(GlobalVar.typedata_g.Msnap_centerX, GlobalVar.typedata_g.Msnap_centerY);
        //                double circleRight = rightline.Distance(GlobalVar.typedata_g.Msnap_centerX, GlobalVar.typedata_g.Msnap_centerY);
        //                double circleLeft = leftline.Distance(GlobalVar.typedata_g.Msnap_centerX, GlobalVar.typedata_g.Msnap_centerY);

        //                double circleSmall = outline[0] - circleLeft;
        //                Cv2.CvtColor(GlobalImage.MeasureMat, GlobalImage.MeasureMat, ColorConversionCodes.GRAY2RGB);
        //                OpenCvSharp.Point centerPoint = new OpenCvSharp.Point(GlobalVar.typedata_g.Msnap_centerX, GlobalVar.typedata_g.Msnap_centerY);
        //                OpenCvSharp.Point centerPointSmall = new OpenCvSharp.Point(GlobalVar.typedata_g.Msnap_centerX, GlobalVar.typedata_g.Msnap_centerY + 150);
        //                OpenCvSharp.Point upPoint = new OpenCvSharp.Point(1200, 1400 - circleUp);
        //                OpenCvSharp.Point downPoint = new OpenCvSharp.Point(1200, 1400 + circleDown);
        //                OpenCvSharp.Point leftPoint = new OpenCvSharp.Point(1200 - circleLeft, 1400);
        //                OpenCvSharp.Point rightPoint = new OpenCvSharp.Point(1200 + circleRight, 1400);
        //                OpenCvSharp.Point smallPoint = new OpenCvSharp.Point(1200 + circleSmall, 1550);

        //                Cv2.ArrowedLine(GlobalImage.MeasureMat, centerPoint, upPoint, Scalar.Red, 15);
        //                Cv2.ArrowedLine(GlobalImage.MeasureMat, centerPoint, downPoint, Scalar.Red, 15);
        //                Cv2.ArrowedLine(GlobalImage.MeasureMat, centerPoint, leftPoint, Scalar.Red, 15);
        //                Cv2.ArrowedLine(GlobalImage.MeasureMat, centerPoint, rightPoint, Scalar.Red, 15);
        //                Cv2.ArrowedLine(GlobalImage.MeasureMat, centerPointSmall, smallPoint, Scalar.Red, 15);

        //                displalyImage.displayImage_M(GlobalImage.MeasureMat);
        //                //displalyImage.displayImage_F(output);
        //                displalyInfo.displayInfoMain("圆心到上边距离：" + circleUp.ToString("#0.000") + "  /  " + "圆心到下边距离：" + circleDown.ToString("#0.000"));
        //                displalyInfo.displayInfoMain("圆心到左边距离：" + circleLeft.ToString("#0.000") + "  /  " + "圆心到右边距离：" + circleRight.ToString("#0.000"));
        //                displalyInfo.displayInfoMain("圆心到短边距离：" + circleSmall.ToString("#0.000"));
        //                displalyInfo.displayInfoMain("处理时间：" + sw.ElapsedMilliseconds.ToString());

        //                #endregion
        //                xy[0] = result[0];
        //                xy[1] = result[1];
        //                xy[2] = result[2];
        //                xy[3] = result[3];
        //                xy[4] = result[4];
        //                return xy;
        //            }
        //            catch (System.Exception ex)
        //            {
        //                displalyInfo.displayInfoMain("识别出错：" + ex.Message);
        //                return null;
        //            }
        //        });

        //        return temp;
        //    }
    }
}
